/*--------------------------------------------------------------------------
Modified from GNU Group's SDCC
Only for study purpose
---------------------------------------------------------------------------*/

#include <stdio.h>
#include "common.h"
#include "SymbolTable.h"

FILE *pFileRule;
extern int yyparse();
extern FILE *yyin;
extern char *filename;
extern char *lexFilename;

char *fullSrcFileName;				/* source input file name */
char *fullDstFileName;				/* dest output file name */
char *cmdOutput[MAX_STRING_LEN];	/* command line output string */

/* preprocessor application name */
const char *_preCmdApp = "sdcpp.exe";

bool b_Pre = true;
bool b_View = false;

/*--------------------------*/
/* process argument */
/*--------------------------*/
bool processArg(char **argv, int count)
{
	FILE * test = NULL;
	char * buff;
	int idx = 1;
	if (count < 2)
	{
		printf("Command line is invalid!\n");
		printf("Usage: CCompiler input [output] [options]\n");
		printf("Options\n");
		printf(" -n    Don't use preprocessor\n");
		printf(" -v    View symbol table information\n");
		printf("In/Out file\n");
		printf("  input : source file\n");
		printf("  output: iCode output file\n");
		return false;
	}
	
	buff = argv[idx++];
	test = fopen(buff, "rb");

	if (test != NULL)
	{
		if (fullSrcFileName == NULL)
			fullSrcFileName = (char *)Safe_alloc(MAX_STRING_LEN);
		if (fullDstFileName == NULL)
			fullDstFileName = (char *)Safe_alloc(MAX_STRING_LEN);

		strcpy(fullSrcFileName, buff);
		
		if (count >= 3 && argv[idx][0] != '-')
			strcpy(fullDstFileName, argv[idx++]);
		else
		{
			strcpy(fullDstFileName, buff);
			fullDstFileName[strlen(fullDstFileName) - 2] = 0;
			strcat(fullDstFileName, "_iCode.txt");
		}

		while (idx < count && argv[idx][0] == '-')
		{
			if (argv[idx][1] == 'n')
				b_Pre = false;
			else if (argv[idx][1] == 'v')
				b_View = true;
			idx++;
		}

		/* commented by nttrung */
		/* undo comment to pass direct source file to CCompiler */
		if (!b_Pre)
		{
			lexFilename = fullSrcFileName; 
			filename = lexFilename;
		}

		return true;
	}
	else
		printf("can't open source file \"%s\"\n", argv[1]);

	return false;
}

/*--------------------------*/
/* preprocessor */
/*--------------------------*/
bool preProcess()
{
	int i;

	if (fullSrcFileName == NULL)
	{
		printf ("source file not found\n");
		exit (EXIT_FAILURE);
	}

	/* calling preprocessor...*/
	buildCmdLinePre(cmdOutput, MAX_STRING_LEN, _preCmdApp, fullSrcFileName);

	/* check output cmd */
	assert(cmdOutput);

	yyin = _popen(cmdOutput, "rt");

	/* delay for read output command prompt */
	for (i = 0; i< 10000000; i++)
	{
	  int a = 3*4*i;
	}

	/* check output */
	if (yyin == NULL) {
	  perror ("PreProcess file not found\n");
	  exit (EXIT_FAILURE);
	}
}

void viewAllTable()
{
	printf("\nSymbol table");
	viewTable(stdout, SymbolTab, 0, 255);

	printf("\nTypedef table");
	viewTable(stdout, TypedefTab, 0, 255);

	printf("\nStructTab table");
	viewTable(stdout, StructTab, 0, 255);

	/* view memory sumary on console*/
	printf("\n");
	viewSeg(stdout, data);

	printf("\n");
	viewSeg(stdout, code);

	printf("\n");
	viewStackSeg(stdout, stack);
}


/*--------------------------*/
/* main function */
/*--------------------------*/
int main(int argc, char **argv)
{
	processArg(argv, argc);	/* process argument */

	/* input file is valid */
	if (fullSrcFileName)
	{
		if (b_Pre)
			preProcess();		/* pre process */
		else
			yyin = fopen(fullSrcFileName, "rt");

		initSymt ();		/* init symbol table */
		initMem ();			/* init memory segment */

		yyparse();			/* parse */

		if (b_View)
			viewAllTable();

		/* view memory summary on result file */
		fprintMemToFile("allocMem.txt");

		/* output symbol table summary on result file */
		fprintSymTabToFile("symTab.txt");

		printf("\n");
		yylexsumary();

	}

	getch();
}
